import sys

from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QCheckBox, QLineEdit, QPushButton,\
                                QHBoxLayout, QApplication, QSpacerItem, QStyle, QToolButton, QGroupBox, \
                                QSizePolicy, QComboBox, QScrollArea
from PySide6.QtCore import Qt, Signal, Slot
from PySide6.QtGui import QDesktopServices


from .invoice_field import FieldSelectBox
from api import api_ui

# 出于严谨，可能一些clicked要换成toggled信号

class InvoiceUi(QWidget):
    rel_tip_signal = Signal(str, str)
    show_msg_signal = Signal(dict)

    def __init__(self, group_box_style: str):
        super().__init__()
        self.GROUP_BOX_STYLE = group_box_style
        self.all_checkbox = []          # 存储所有的checkbox
        self.able_rule = {}
        self.setup_ui()

    def setup_ui(self):
        spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        # 密钥box
        secret_group_box = QGroupBox('密钥')
        secret_group_box.setStyleSheet(self.GROUP_BOX_STYLE)
        secret_group_layout = QVBoxLayout(secret_group_box)
        first_row_layout = QHBoxLayout()
        doc_url_btn = QPushButton('API文档')
        doc_url_btn.setToolTip('点击打开网址')
        doc_url_btn.clicked.connect(lambda: QDesktopServices.openUrl('https://cloud.tencent.com/document/product/866/33515'))
        doc_url_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        key_url_btn = QPushButton('访问密钥')
        key_url_btn.setToolTip('点击打开网址')
        key_url_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        key_url_btn.clicked.connect(lambda: QDesktopServices.openUrl('https://console.cloud.tencent.com/cam/capi'))
        key_tip_btn = QToolButton()
        key_tip_btn.setFixedSize(15, 15)
        key_tip_btn.setIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation))
        key_tip_btn.setToolTip('识别功能通过腾讯云的OCR服务实现，请先在腾讯云官网申请API密钥')
        first_row_layout.addItem(spacer)
        first_row_layout.addWidget(doc_url_btn)
        first_row_layout.addItem(spacer)
        first_row_layout.addWidget(key_url_btn)
        first_row_layout.addWidget(key_tip_btn)
        first_row_layout.addItem(spacer)
        
        sec_row_layout = QHBoxLayout()
        self.input_secret_ckbox = QCheckBox('手动输入密钥：')
        self.input_secret_ckbox.setObjectName('input_secret_ckbox')
        self.input_secret_ckbox.toggled.connect(self.enable_and_disable)
        id_label = QLabel('API ID：')
        self.id_edit = QLineEdit()
        self.id_edit.setEnabled(False)
        key_label = QLabel('API KEY：')
        self.key_edit = QLineEdit()
        self.key_edit.setEnabled(False)
        sec_row_layout.addWidget(self.input_secret_ckbox)
        sec_row_layout.addWidget(id_label)
        sec_row_layout.addWidget(self.id_edit)
        sec_row_layout.addWidget(key_label)
        sec_row_layout.addWidget(self.key_edit)

        third_row_layout = QHBoxLayout()
        self.select_file_ckbox = QCheckBox('选择密钥文件：')
        self.select_file_ckbox.setObjectName('select_file_ckbox')
        self.select_file_ckbox.setChecked(True)
        self.select_file_ckbox.toggled.connect(self.enable_and_disable)
        
        self.csv_edit = QLineEdit()
        self.csv_btn = api_ui.SelectButton(self.csv_edit, 'CSV Files (*.csv)', False)
        third_row_layout.addWidget(self.select_file_ckbox)
        third_row_layout.addWidget(self.csv_edit)
        third_row_layout.addWidget(self.csv_btn)

        self.all_checkbox.append([self.input_secret_ckbox, self.select_file_ckbox])
        self.input_secret_ckbox.clicked.connect(self.ckbox_clicked)
        self.select_file_ckbox.clicked.connect(self.ckbox_clicked)

        secret_group_layout.addLayout(first_row_layout)
        secret_group_layout.addLayout(sec_row_layout)
        secret_group_layout.addLayout(third_row_layout)

        # 接口box
        api_group_box = QGroupBox('接口')
        api_group_box.setStyleSheet(self.GROUP_BOX_STYLE)
        api_group_layout = QVBoxLayout(api_group_box)
        forth_row_layout = QHBoxLayout()
        self.api1_ckbox = QCheckBox('接口1')
        self.api1_ckbox.clicked.connect(self.ckbox_clicked)
        api1_btn = QToolButton()
        api1_btn.setFixedSize(15, 15)
        api1_btn.setIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation))
        api1_btn.setToolTip('通用票据识别（高级版），5次/秒')
        self.api2_ckbox = QCheckBox('接口2')
        self.api2_ckbox.clicked.connect(self.ckbox_clicked)
        api2_btn = QToolButton()
        api2_btn.setFixedSize(15, 15)
        api2_btn.setIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation))
        api2_btn.setToolTip('增值税发票识别，10次/秒')
        self.api1_ckbox.setChecked(True)
        forth_row_layout.addWidget(self.api1_ckbox)
        forth_row_layout.addWidget(api1_btn)
        forth_row_layout.addItem(spacer)
        forth_row_layout.addWidget(self.api2_ckbox)
        forth_row_layout.addWidget(api2_btn)
        forth_row_layout.addItem(spacer)
        forth_row_layout.setSpacing(0)
        file_type_tip = QLabel('支持PNG、JPG、JPEG、PDF，不支持 GIF、OFD 格式')
        api_group_layout.addLayout(forth_row_layout)
        api_group_layout.addWidget(file_type_tip)
        api_group_layout.addWidget(file_type_tip)

        self.all_checkbox.append([self.api1_ckbox, self.api2_ckbox])

        # 字段选择box
        self.field_select_box = FieldSelectBox(self.GROUP_BOX_STYLE)


        # 识别box
        recognize_box = QGroupBox('识别')
        recognize_box.setStyleSheet(self.GROUP_BOX_STYLE)
        recognize_layout = QVBoxLayout(recognize_box)
        fifth_row_layout = QHBoxLayout()
        fifth_row_layout.addWidget(QLabel('选择发票：'))
        self.file_path_edit = QLineEdit()
        file_type = '*.png *.jpg *.jpeg *.pdf'
        self.file_path_btn = api_ui.SelectButton(self.file_path_edit, file_type, self.file_path_edit)
        fifth_row_layout.addWidget(self.file_path_edit)
        fifth_row_layout.addWidget(self.file_path_btn)

        sixth_row_layout = QHBoxLayout()
        self.sort_ckbox = QCheckBox('识别结果排序：')
        self.sort_ckbox.setObjectName('sort_ckbox')
        self.sort_ckbox.setChecked(True)
        self.sort_ckbox.clicked.connect(self.enable_and_disable)
        self.sort_ckbox.clicked.connect(self.sort_ckbox_checked)
        sort_btn = QToolButton()
        sort_btn.setFixedSize(15, 15)
        sort_btn.setIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation))
        sort_btn.setToolTip('不勾选则无序排列')
        self.sort_by_cbox = QComboBox()
        self.sort_by_cbox.addItems(['', '发票号码', '发票金额', '税额'])
        self.sort_by_cbox.setCurrentIndex(1)
        self.sort_order_cbox = QComboBox()
        self.sort_order_cbox.setMinimumWidth(70)
        self.sort_order_cbox.addItems(['', '升序', '降序'])
        self.sort_order_cbox.setCurrentIndex(1)
        
        sixth_row_layout.addWidget(sort_btn)
        sixth_row_layout.addWidget(self.sort_ckbox)
        sixth_row_layout.addWidget(QLabel('排序依据：'))
        sixth_row_layout.addWidget(self.sort_by_cbox)
        sixth_row_layout.addWidget(QLabel('排序次序：'))
        sixth_row_layout.addWidget(self.sort_order_cbox)
        sixth_row_layout.addItem(spacer)
        
        # 开始按钮
        self.start_btn = QPushButton('开始识别')

        recognize_layout.addLayout(fifth_row_layout)
        recognize_layout.addLayout(sixth_row_layout)
        recognize_layout.addWidget(self.start_btn, alignment=Qt.AlignCenter)


        # 宏观布局
        main_layout = QVBoxLayout(self)
        main_layout.setSpacing(20)
        main_layout.addWidget(secret_group_box)
        main_layout.addWidget(api_group_box)
        main_layout.addWidget(self.field_select_box)
        main_layout.addWidget(recognize_box)

        # 添加self.able_rule
        self.able_rule['input_secret_ckbox'] = [self.id_edit, self.key_edit]
        self.able_rule['select_file_ckbox'] = [self.csv_edit, self.csv_btn]
        self.able_rule['sort_ckbox'] = [self.sort_by_cbox, self.sort_order_cbox]
    
    def run(self):
        if self.input_secret_ckbox.isChecked():
            secret_id = self.id_edit.text()
            secret_key = self.key_edit.text()
            if secret_id and secret_key:
                self.run_thread(secret_id, secret_key)
            else:
                self.add_result_tip('请输入密钥', 'red')
                return
        else:
            file_path = self.csv_edit.text()
            if not file_path:
                self.add_result_tip('请选择下载的CSV密钥文件', 'red')
                return
            with open(file_path, 'r', encoding='utf-8') as f:
                file_content = f.read().split()
                secret_id, secret_key = file_content[1].split(',')
        api_choice = '1' if self.api1_ckbox.isChecked() else '2'
        invoice_fields = []
        for i in range(self.field_select_box.display_columns.count()):
            text = self.field_select_box.display_columns.item(i).text()
            invoice_fields.append(text)
        invoice_path = self.file_path_edit.text()

    @Slot()
    def ckbox_clicked(self):
        # 设置互斥关系
        # 要定义一个 all_checkbox，用来保存所有关联的 checkbox
        # 通过 self.sender() 获取发送信号的对象，再通过 self.all_checkbox 找到其他关联的 checkbox
        current_checkbox = self.sender()
        for box_list in self.all_checkbox:
            if current_checkbox in box_list:
                current_boxlist = box_list
        length = len(current_boxlist)
        state = current_checkbox.isChecked()
        if state:
            for box in current_boxlist:
                if box == current_checkbox:
                    continue
                box.setChecked(False)
        else:
            if length == 2:
                # exclusive_checkbox = box_list[abs(box_list.index(current_checkbox) - 1)]        # 两种写法
                exclusive_checkbox, = [x for x in current_boxlist if x != current_checkbox]
                exclusive_checkbox.setChecked(True)

    @Slot()
    def enable_and_disable(self):
        current_cbox = self.sender()
        rule = self.able_rule[current_cbox.objectName()]
        for item in rule:
            item.setEnabled(current_cbox.isChecked())

    @Slot()
    def sort_ckbox_checked(self):
        if self.sort_ckbox.isChecked():
            self.sort_by_cbox.setCurrentIndex(1)
            self.sort_order_cbox.setCurrentIndex(1)
        else:
            self.sort_by_cbox.setCurrentText('')
            self.sort_order_cbox.setCurrentText('')

    @Slot(bool)
    def receive_decision(self, choice):
        """槽函数，用于接收用户选择"""
        self.user_choice = choice

class InvoiceUiScroll(QScrollArea):
    rel_tip_signal = Signal(str, str)
    show_msg_signal = Signal(dict)
    send_to_subthread_signal = Signal(bool)
    log_signal = Signal(str, str)

    def __init__(self, group_box_style: str):
        super().__init__()
        self.setStyleSheet("QScrollArea { border: none; }")        # 设置样式表，消除白线
        self.setWidgetResizable(True)
        invoice_ui = InvoiceUi(group_box_style)
        invoice_ui.rel_tip_signal.connect(self.rel_tip_signal)
        invoice_ui.show_msg_signal.connect(self.show_msg_signal)
        self.send_to_subthread_signal.connect(invoice_ui.receive_decision)
        self.setWidget(invoice_ui)

    @Slot(bool)
    def receive_decision(self, choice):
        """槽函数，用于接收用户选择，并发送给子线程"""
        self.send_to_subthread_signal.emit(choice)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = InvoiceUiScroll()
    ui.show()
    sys.exit(app.exec())

